#!/usr/bin/env python2.7

import ConfigParser
import datetime
import optparse
import os
import sys

import jinja2

from venya.lib import stdlib, cmdparser, exception
from lib import aclparser
from lib.base import GypsumError

def printdate(value = 0):
   retval = None
   if value == 0:
      retval = datetime.datetime.now().strftime("%a, %B %d, %Y %T %p")
   elif value == 1:
      retval = datetime.datetime.now().strftime("%D %X")

   return retval

class gypsum(cmdparser.GetOpt):
    option_list = (
            optparse.make_option("-p", "--policy", type = "str",
                help = "Config file", dest = "policy"),
            optparse.make_option("-t", "--template", type = "str",
                help = "Template file", dest = "template"),
            optparse.make_option("-c", "--config", type = "str",
                help = "Config file for gypsum", default = "gypsum.conf",
                dest = "config"),
    ) + cmdparser.GetOpt.option_list

    help = """
    JunOS and Juniper SRX firewall policy generator program
    """

    usage = "[ options ] file"

    def __init__(self, **kwargs):
        super(gypsum, self).__init__(**kwargs)
        self.__parser = None

    def _getTemplate(self, option):
        retval = None
        main = None
        try:
            main = os.path.expandvars(self.__parser.get("main", "template"))
        except ConfigParser.NoOptionError as err:
            self.error(err)

        opttmpl = None
        try:
            opttmpl = os.path.expandvars(self.__parser.get(option, "template"))
        except ConfigParser.NoOptionError as err:
            pass

        if opttmpl:
            retval = opttmpl
        else:
            retval = main

        return self._loadTemplate(retval)

    def _loadTemplate(self, templatefile):
        retval = None
        try:
            jenv = jinja2.Environment(
                    extensions = [ "jinja2.ext.do" ],
                    loader = jinja2.FileSystemLoader(os.path.dirname(
                        templatefile)),
                        keep_trailing_newline = True,
                        lstrip_blocks = True,
                        trim_blocks = True)
            jenv.filters['date'] = printdate
            retval = jenv.get_template(os.path.basename(templatefile))
        except jinja2.exceptions.TemplateNotFound as err:
            self.error("%s: %s not found", str(self), str(err))

        return retval

    def _getFilterName(self, policyFile, target):
        if target == "junos":
            ext = "jcl"
        elif target == "srx":
            ext = "srx"

        return "%s.%s" %(os.path.basename(policyFile).split(".")[0], ext)

    @cmdparser.getopts
    def handle(self):
        if self.options.config:
            self.__parser = ConfigParser.SafeConfigParser()
            if os.path.exists(self.options.config):
                self.__parser.read(self.options.config)
            else:
                self.error("%s %s does NOT exist", str(self),
                        self.options.config)
        else:
            self.error("%s: no config file defined", str(self))

        config = None
        try:
            if self.options.policy:
                if os.path.exists(self.options.policy):
                    config = aclparser.parse_config(self.options.policy,
                            self.options.config)
                else:
                    self.error("%s: %s does NOT exist", str(self),
                            self.options.policy)
            else:
                self.error("%s: no policy defined!", str(self))
        except GypsumError as err:
            self.error("%s: %s", str(self), str(err))

        filterdir = None
        try:
            filterdir = os.path.expandvars(
                    self.__parser.get("main", "filterdir"))
        except ConfigParser.NoOptionError as err:
            pass

        if config and config.header and config.terms:
            items = {}
            template = self._getTemplate(config.header["target"])
            items["header"] = config.header
            items["terms"] = config.terms
            items["pfls"] = config.pfls
            items["first"] = True
            items["filename"] = self._getFilterName(self.options.policy,
                    config.header["target"])
            if os.path.exists(filterdir):
                output = "%s/%s" %(filterdir, items["filename"])
                with open(output, "w") as fh:
                    fh.write(template.render(items))
            else:
                print(template.render(items))

if __name__ == "__main__":
    instance =  None
    try:
        instance = gypsum(version = 0.1, args = sys.argv)
        if instance.length <= 1:
            instance.printhelp()
        else:
            instance.handle()
    except exception.GetOptError as err:
        print(err)
        sys.exit(1)

